package com.tieshan.smartwindow.widget

import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatTextView
import com.tieshan.smartwindow.widget.MyMarqueeTextView
import com.tieshan.smartwindow.widget.MyMarqueeTextView.OnMarqueeListener
import android.widget.TextView
import android.view.Choreographer
import org.w3c.dom.Text
import timber.log.Timber
import java.lang.Exception

/**
 * author : Hleo
 * time   : 2022/3/24
 * desc   :  跑马灯滚动监听
 */
class MyMarqueeTextView : androidx.appcompat.widget.AppCompatTextView {
    private val TAG = MyMarqueeTextView::class.java.simpleName
    private var onMarqueeListener: OnMarqueeListener? = null

    constructor(context: Context?) : super(context!!) {}
    constructor(context: Context?, attrs: AttributeSet?) : super(
        context!!, attrs
    ) {
    }

    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context!!, attrs, defStyleAttr
    ) {
    }

    private fun init(context: Context) {}
    override fun setSelected(selected: Boolean) {
        super.setSelected(selected)
    }

    override fun post(action: Runnable): Boolean {
        return super.post(action)
    }

    private var isInit = false
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        try {
            if (!isInit) {
                val marquee = TextView::class.java.getDeclaredField("mMarquee")
                if (marquee != null) {
                    marquee.isAccessible = true
                    val obj = marquee[this]
                    if (obj != null) {
                        val cls: Class<*> = obj.javaClass
                        val field = cls.getDeclaredField("mStatus")
                        if (field != null) {
                            field.isAccessible = true
                        }
                        val field1 = cls.getDeclaredField("mRestartCallback")
                        if (field1 != null) {
                            isInit = true
                            field1.isAccessible = true
                            field1[obj] = mRestartCallback
                        }
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun setMarqueeListener(onMarqueeListener: OnMarqueeListener?) {
        this.onMarqueeListener = onMarqueeListener
    }

    private val mRestartCallback = Choreographer.FrameCallback {
        try {
            val marquee = this@MyMarqueeTextView.javaClass.superclass.getDeclaredField("mMarquee")
            if (marquee != null) {
                marquee.isAccessible = true
                val obj = marquee[this@MyMarqueeTextView]
                if (obj != null) {
                    val cls: Class<*> = obj.javaClass
                    val field = cls.getDeclaredField("mStatus")
                    if (field != null) {
                        field.isAccessible = true
                        val mStatus = (field[obj] as Byte).toByte()
                        if (mStatus == MARQUEE_RUNNING) {
                            val field1 = cls.getDeclaredField("mRepeatLimit")
                            field1.isAccessible = true
                            var mRepeatLimit = (field1[obj] as Int).toInt()
                            if (mRepeatLimit >= 0) {
                                mRepeatLimit--
                            }
                            if (onMarqueeListener != null) {
                                onMarqueeListener!!.onMarqueeRepeateChanged(mRepeatLimit)
                            }
                            val method = cls.getDeclaredMethod("start", Integer.TYPE)
                            method.isAccessible = true
                            method.invoke(obj, mRepeatLimit)
                        }
                    }
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Timber.e(e.toString())
        }
    }

    //状态监听接口
    interface OnMarqueeListener {
        fun onMarqueeRepeateChanged(repeatLimit: Int)
    }

    companion object {
        private const val MARQUEE_STOPPED: Byte = 0x0
        private const val MARQUEE_STARTING: Byte = 0x1
        private const val MARQUEE_RUNNING: Byte = 0x2
    }

    override fun onFocusChanged(
        focused: Boolean, direction: Int,
        previouslyFocusedRect: Rect?
    ) {
        if (focused) super.onFocusChanged(focused, direction, previouslyFocusedRect)
    }

    override fun onWindowFocusChanged(focused: Boolean) {
        if (focused) super.onWindowFocusChanged(focused)
    }

    override fun isFocused(): Boolean {
        return true
    }
}